/*
 * 微服务插件
 * Copyright(c) 2016-2017 liumurong
 * 
 * */


import { Eureka } from "eureka-ts-client";
import * as Router from 'koa-router';
import * as koa from 'koa';
import * as os from 'os';
import * as path from 'path';

/**
 * Eureka参数选项
 */
export interface EurekaOptions {
    ip?: string,
    port?: number,
    appname: string,
    homepage: string
};

/**
 * Eureka配置项
 */
export interface EurekaConfig {
    host: string,
    port: number,
    servicepath: string
}

/**
 * 微服务模块
 */
export class EurekaService {

    private ip: string;
    private port: number;
    private appname: string;
    private homepage: string;
    private eurekaClient: Eureka;
    private eurekaConfig: EurekaConfig;
    private router: Router;

    constructor(opts: EurekaOptions, config: EurekaConfig) {

        this.ip = opts.ip || this.getLocalHost();
        this.port = opts.port || 80;
        this.appname = opts.appname;
        this.homepage = opts.homepage;

        this.eurekaConfig = config;
        this.initEurekaClient();
        this.initRouters();
    }
    /**
     * 初始化eureka对象
     */
    private initEurekaClient() {
        this.eurekaClient = new Eureka({
            instance: {
                app: this.appname,
                instanceId: os.hostname() + ":" + this.appname + ":" + this.port,
                hostName: this.ip,
                ipAddr: this.ip,
                statusPageUrl: 'http://' + this.ip + ":" + this.port + '/info',
                port: {
                    "$": this.port,
                    "@enabled": true
                },
                vipAddress: this.appname,
                dataCenterInfo: {
                    "@class": "com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo",
                    name: "MyOwn"
                },
                homePageUrl: "http://" + this.ip + ":" + this.port + this.homepage,
                healthCheckUrl: "http://" + this.ip + ":" + this.port + "/health"
            },
            eureka: {
                host: this.eurekaConfig.host,
                port: this.eurekaConfig.port,
                servicePath: this.eurekaConfig.servicepath,
                fetchRegistry: true,
                preferSameZone: true
            }
        });

    }

    /**
     * 初始化一些默认路由
     */
    private initRouters() {
        this.router = new Router();
        /**
        * 信息接口
        */
        this.router.all('/info', async (ctx: Router.IRouterContext, next: () => Promise<any>) => {
            ctx.body = {
                "app": this.appname,
                "auth": "liumurong"
            };
        });
        /**
         * 心跳接口
         */
        this.router.get('/health', async (ctx: Router.IRouterContext, next: () => Promise<any>) => {
            ctx.body = {
                "status": "UP"
            };
        });
    }

    /**
     * 获取本机IP地址
     * docker中是否有问题?
     */
    private getLocalHost(): string {
        let interfaces = os.networkInterfaces();
        for (let devName in interfaces) {
            let iface = interfaces[devName];
            for (let i = 0; i < iface.length; i++) {
                let alias = iface[i];
                if (alias.family === "IPv4" && alias.address !== "127.0.0.1" && !alias.internal) {
                    return alias.address;
                }
            }
        }
        return "127.0.0.1";
    }

    /**
     * 获取eureka所必须的一些接口
     */
    getEurekaRouters(): koa.Middleware {
        return this.router.routes();
    }

    /**
     * 启动
     */
    start() {
        if (this.eurekaClient) {
            this.eurekaClient.start();
        }
    }
    /**
     * 停止
     */
    stop() {
        if (this.eurekaClient) {
            this.eurekaClient.stop();
        }
    }

}